/**
* @file app_cluster_color_control.c
* @brief Common process - adapter the flash api
* @version 0.1
* @date 2021-10-22
*
* @copyright Copyright 2020-2021 Tuya Inc. All Rights Reserved.
*
*/
#include "tal_log.h"
#include "tal_system.h"
#include "tal_memory.h"
#include "tal_attribute_rw.h"
#include "app_handle.h"
#include "app_cluster_color_control.h"

#define COLOR_TEMP_MIN_MIREDS 153
#define COLOR_TEMP_MAX_MIREDS 500

/**
 * @note app set mode command handler
 * @param [in] {UCHAR_T} mode 
 * @param [in] {ZIGBEE_CMD_T} cmd_type
 * @return: none
 */
STATIC VOID_T __app_color_cmd_set_mode_handler(ZIGBEE_CMD_T cmd_type, UCHAR_T mode)
{
    TAL_SEND_QOS_E QOS = QOS_1;
    ULONG_T delay_ms = 0;

    TAL_PR_DEBUG("Receive  mode : %d", mode);
    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        QOS = QOS_0;
    }

    app_color_report_mode_value(QOS, delay_ms, mode);
    app_onoff_handle_count_down(delay_ms);

    OPERATE_RET ret = app_light_ctrl_data_mode_set((LIGHT_MODE_E)mode);
    if (ret != OPRT_OK)
    {
        return;
    }
    
    app_handle_start(TRUE);
    
    //updata mode attribute
    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_LIGHT_MODE_ATTRIBUTE_ID,
                           &mode,
                           ATTR_INT8U_ATTRIBUTE_TYPE);
}
/**
 * @brief 
 * 
 * @param cmd_type 
 * @param temper 
 */
STATIC VOID_T __app_color_ty_cmd_set_temperature_handler(IN ZIGBEE_CMD_T cmd_type, IN USHORT_T temper)
{
    ULONG_T delay_ms = 0;
    TAL_SEND_QOS_E send_qos = QOS_1;
    OPERATE_RET ret;

    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        send_qos = QOS_0;
    }
    TAL_PR_DEBUG("Receive temper : %d", temper);
    app_color_report_ty_temperature_value(send_qos, delay_ms, temper);
    app_onoff_handle_count_down(delay_ms);
    ret = app_light_ctrl_data_temp_set(temper, 5);
    if (ret != OPRT_OK)
    {
        return;
    }

    app_handle_start(TRUE);

    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_TEMPERATURE_ATTR_ID,
                           &temper,
                           ATTR_INT16U_ATTRIBUTE_TYPE);
}

STATIC VOID_T __app_color_cmd_set_ty_scene_handler(IN ZIGBEE_CMD_T cmd_type, UINT8_T *payload, UINT8_T payload_len)
{
    ULONG_T delay_ms = 0;
    TAL_SEND_QOS_E send_qos = QOS_1;
    OPERATE_RET ret;

    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        send_qos = QOS_0;
    }
    TAL_PR_HEXDUMP_DEBUG("Receive ty_scene:", payload, payload_len);
    app_color_report_ty_scene_value(send_qos, delay_ms, payload, payload_len);
    ret = app_light_ctrl_data_ty_scene_set(payload, payload_len);
    if (ret != OPRT_OK)
    {
        return;
    }
    
    app_handle_start(TRUE);
    
    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_TY_SCENE_ATTR_ID,
                           app_light_ctrl_data_ty_scene_get(),
                           ATTR_ARRAY_ATTRIBUTE_TYPE);
}

STATIC VOID_T __app_color_cmd_set_power_memory_handler(IN ZIGBEE_CMD_T cmd_type, UINT8_T *payload, UINT8_T payload_len)
{
    ULONG_T delay_ms = 0;
    TAL_SEND_QOS_E send_qos = QOS_1;
    OPERATE_RET ret;

    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        send_qos = QOS_0;
    }
    TAL_PR_HEXDUMP_DEBUG("Receive power_memory:", payload, payload_len);
    app_color_report_power_memory_value(send_qos, delay_ms, payload, payload_len);
    ret = app_light_ctrl_data_power_memory_set(payload, payload_len);
    if (ret != OPRT_OK)
    {
        return;
    }
    
    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_POWER_MEMORY_ATTR_ID,
                           app_light_ctrl_data_power_memory_get(),
                           ATTR_ARRAY_ATTRIBUTE_TYPE);
}

STATIC VOID_T __app_color_cmd_set_do_not_disturb_handler(ZIGBEE_CMD_T cmd_type, UCHAR_T no_disturb)
{
    TAL_SEND_QOS_E QOS = QOS_1;
    ULONG_T delay_ms = 0;

    TAL_PR_DEBUG("Receive  do_not_disturb : %d", no_disturb);
    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        QOS = QOS_0;
    }

    app_color_report_do_not_disturb_value(QOS, delay_ms, no_disturb);

    OPERATE_RET ret = app_light_ctrl_data_do_not_disturb_set(no_disturb);
    if (ret != OPRT_OK)
    {
        return;
    }
    
    
    //updata mode attribute
    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_DND_ATTR_ID,
                           &no_disturb,
                           ATTR_BOOLEAN_ATTRIBUTE_TYPE);
}

STATIC VOID_T __app_color_cmd_set_switch_gradient_handler(IN ZIGBEE_CMD_T cmd_type, UINT8_T *payload, UINT8_T payload_len)
{
    ULONG_T delay_ms = 0;
    TAL_SEND_QOS_E send_qos = QOS_1;
    OPERATE_RET ret;

    if (cmd_type == ZIGBEE_CMD_GROUP)
    {
        delay_ms = 10000 + tal_system_get_random(1000);
        send_qos = QOS_0;
    }
    TAL_PR_HEXDUMP_DEBUG("Receive switch_gradient:", payload, payload_len);
    app_color_report_switch_gradient_value(send_qos, delay_ms, payload, payload_len);
    ret = app_light_ctrl_data_switch_gradient_set(payload, payload_len);
    if (ret != OPRT_OK)
    {
        return;
    }

    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_SWITCH_GRADIENT_ATTR_ID,
                           app_light_ctrl_data_switch_gradient_get(),
                           ATTR_ARRAY_ATTRIBUTE_TYPE);
}

/**
 * @brief 
 * 
 * @param cmd_type 
 * @param temper 
 * @param trans_time_100ms 
 */
STATIC VOID_T __app_color_z3_cmd_move_or_step_temperature_handler(ZIGBEE_CMD_T cmd_type, USHORT_T temper, USHORT_T trans_time_100ms)
{
    USHORT_T ty_temper;
    OPERATE_RET ret;
    if (temper >= 500)
    {
        temper = 500;
    }

    if (temper <= 153)
    {
        temper = 153;
    }

    ty_temper = app_light_tools_zig_t_2_app_t(temper);
    TAL_PR_DEBUG("ty_temper%d, temper=%d", ty_temper, temper);

    ret = app_light_ctrl_data_temp_set(ty_temper, trans_time_100ms);
    if (ret == OPRT_INVALID_PARM)
    {
        return;
    }

    app_handle_start(TRUE);

    //Z3 temperature
    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           ATTR_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
                           &temper,
                           ATTR_INT16U_ATTRIBUTE_TYPE);

    //tuya temper
    tal_zg_write_attribute(1,
                           CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                           TY_ATTR_TEMPERATURE_ATTR_ID,
                           &ty_temper,
                           ATTR_INT16U_ATTRIBUTE_TYPE);
}

/**
 * @note report temperature attribute value
 * @param [in] {TAL_SEND_QOS_E} QOS 
 * @param [in] {USHORT_T} delay_ms
 * @param [in] {USHORT_T} temperature
 * @return: none
 */
VOID_T app_color_report_temperature_value(TAL_SEND_QOS_E qos, USHORT_T delay_ms, USHORT_T temperature)
{
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = delay_ms;
    send_data.zcl_id = ZCL_ID_TEMPER;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;
    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;
    send_data.addr.type.dev.dst_ep = 1;
    send_data.addr.type.dev.src_ep = 1;
    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = ATTR_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID;
    send_data.data.zg.attr[0].type = ATTR_INT16U_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = 2;
    send_data.data.zg.attr[0].value[0] = temperature;
    send_data.data.zg.attr[0].value[1] = temperature >> 8;

    //tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 1000);
    TAL_PR_DEBUG("Report temperature qos:%d VALUE %d", qos, temperature);
}
VOID_T rpt_temperature_cb(TAL_SEND_ST_E st, TAL_ZG_SEND_DATA_T *dcb)
{
    TAL_PR_DEBUG("Run Into>>>%s", __FUNCTION__);
    TAL_PR_DEBUG("ST:%d", st);
}
/**
 * @note report tuya temperature attribute value
 * @param [in] {TAL_SEND_QOS_E} qos 
 * @param [in] {USHORT_T} delay_ms
 * @param [in] {USHORT_T} temperature
 * @return: none
 */
VOID_T app_color_report_ty_temperature_value(TAL_SEND_QOS_E qos, USHORT_T delay_ms, USHORT_T temperature)
{
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = delay_ms;
    send_data.zcl_id = ZCL_ID_TEMPER;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_GLOBAL;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;

    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.src_ep = 1;
    send_data.addr.type.dev.dst_ep = 1;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;

    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = TY_ATTR_TEMPERATURE_ATTR_ID;
    send_data.data.zg.attr[0].type = ATTR_INT16U_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = 2;
    send_data.data.zg.attr[0].value[0] = temperature;
    send_data.data.zg.attr[0].value[1] = temperature >> 8;

    //tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 1000);
    TAL_PR_NOTICE("Report temperature qos:%d VALUE %d", qos, temperature);
}

VOID_T app_color_report_ty_scene_value(TAL_SEND_QOS_E qos, USHORT_T delay_ms, UINT8_T *payload, UINT8_T payload_len)
{
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = delay_ms;
    send_data.zcl_id = ZCL_ID_TY_SCENE;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_GLOBAL;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;

    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.src_ep = 1;
    send_data.addr.type.dev.dst_ep = 1;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;

    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = TY_ATTR_TY_SCENE_ATTR_ID;
    send_data.data.zg.attr[0].type = ATTR_ARRAY_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = payload_len + 1;
    send_data.data.zg.attr[0].value[0] = payload_len;
    tal_system_memcpy(&send_data.data.zg.attr[0].value[1], payload, payload_len);

    //tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 1000);
}

VOID_T app_color_report_power_memory_value(TAL_SEND_QOS_E qos, USHORT_T delay_ms, UINT8_T *payload, UINT8_T payload_len)
{
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = delay_ms;
    send_data.zcl_id = ZCL_ID_POWER_MEMORY;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_GLOBAL;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;

    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.src_ep = 1;
    send_data.addr.type.dev.dst_ep = 1;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;

    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = TY_ATTR_POWER_MEMORY_ATTR_ID;
    send_data.data.zg.attr[0].type = ATTR_ARRAY_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = payload_len + 1;
    send_data.data.zg.attr[0].value[0] = payload_len;
    tal_system_memcpy(&send_data.data.zg.attr[0].value[1], payload, payload_len);

    //tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 1000);
}

VOID_T app_color_report_do_not_disturb_value(TAL_SEND_QOS_E Qos, USHORT_T delay_ms, UINT8_T no_disturb)
{
    TAL_ZG_SEND_DATA_T send_data;

    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.delay_time = delay_ms;
    send_data.random_time = 0;
    send_data.zcl_id = ZCL_ID_DO_NOT_DISTURB;
    send_data.qos = Qos;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_GLOBAL;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;

    // unicast to gateway
    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.dst_ep = 0x01;
    send_data.addr.type.dev.src_ep = TUYA_PRIMARY_ENDPOINT;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;

    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = TY_ATTR_DND_ATTR_ID;
    send_data.data.zg.attr[0].type = ATTR_BOOLEAN_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = 1;
    send_data.data.zg.attr[0].value[0] = no_disturb;
    tal_zg_send_data(&send_data, NULL, 2000);
    TAL_PR_DEBUG("Report do not disturb qos:%d VALUE %d", Qos, no_disturb);
}

VOID_T app_color_report_switch_gradient_value(TAL_SEND_QOS_E qos, USHORT_T delay_ms, UINT8_T *payload, UINT8_T payload_len)
{
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = delay_ms;
    send_data.zcl_id = ZCL_ID_SWITCH_GRADIENT;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_GLOBAL;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;

    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.src_ep = 1;
    send_data.addr.type.dev.dst_ep = 1;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;

    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = TY_ATTR_SWITCH_GRADIENT_ATTR_ID;
    send_data.data.zg.attr[0].type = ATTR_ARRAY_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = payload_len + 1;
    send_data.data.zg.attr[0].value[0] = payload_len;
    tal_system_memcpy(&send_data.data.zg.attr[0].value[1], payload, payload_len);

    //tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 1000);
}

/**
 * @note report mode attribute value
 * @param [in]{TAL_SEND_QOS_E} Qos
 * @param [in]{USHORT_T} delay_ms
 * @param [in]{UCHAR_T} mode
 * @return: none
 */
VOID_T app_color_report_mode_value(TAL_SEND_QOS_E qos, USHORT_T delay_ms, UCHAR_T mode)
{
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, sizeof(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = delay_ms;
    send_data.zcl_id = ZCL_ID_MODE;
    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.command_id = CMD_REPORT_ATTRIBUTES_COMMAND_ID;
    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.cluster_id = CLUSTER_COLOR_CONTROL_CLUSTER_ID;
    send_data.addr.type.dev.src_ep = 1;
    send_data.addr.type.dev.dst_ep = 1;
    send_data.data.zg.attr_sum = 1;
    send_data.data.zg.attr[0].attr_id = TY_ATTR_LIGHT_MODE_ATTRIBUTE_ID;
    send_data.data.zg.attr[0].type = ATTR_INT8U_ATTRIBUTE_TYPE;
    send_data.data.zg.attr[0].size = 1;
    send_data.data.zg.attr[0].value[0] = mode;

    //tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 1000);
    TAL_PR_DEBUG("Report mode qos:%d VALUE %d", qos, mode);
}

/**
 * @brief 
 * 
 * @param cmd 
 * @param payload 
 * @param payload_len 
 * @param cmd_type 
 * @return OPERATE_RET 
 */
OPERATE_RET app_color_cluster_handler(UCHAR_T cmd, UINT8_T *payload, UINT8_T payload_len, ZIGBEE_CMD_T cmd_type)
{
    UCHAR_T option_mask = 0, option_override = 0, option;
    UINT8_T onoff = app_light_ctrl_data_switch_get();
    
    switch (cmd)
    {
    case CMD_MOVE_TO_COLOR_TEMPERATURE_COMMAND_ID:
    {

        if (payload_len == 6)
        {
            option_mask = payload[payload_len - 2];
            option_override = payload[payload_len - 1];
        }
        option = app_zcl_get_option_value(CLUSTER_LEVEL_CONTROL_CLUSTER_ID, option_mask, option_override);
        if (1 == onoff || option == 0x01)
        {
            USHORT_T temperature = (USHORT_T)payload[0] + ((USHORT_T)payload[1] << 8);
            USHORT_T transtime = (USHORT_T)payload[2] + ((USHORT_T)payload[3] << 8);
            TAL_PR_DEBUG("temperature= %d, transtime=%d", temperature, transtime);
            __app_color_z3_cmd_move_or_step_temperature_handler(cmd_type, temperature, transtime);
        }
        break;
    }
    case CMD_STOP_MOVE_STEP_COMMAND_ID:
    {
        app_light_ctrl_data_move_stop();
        break;
    }
    case CMD_MOVE_COLOR_TEMPERATURE_COMMAND_ID:
    {
        if (payload_len == 6)
        {
            option_mask = payload[payload_len - 2];
            option_override = payload[payload_len - 1];
        }
        option = app_zcl_get_option_value(CLUSTER_LEVEL_CONTROL_CLUSTER_ID, option_mask, option_override);
        if (onoff == 1 || option == 0x01)
        {
            USHORT_T cur_temper = 0;
            USHORT_T tar_temper = 0;
            UCHAR_T move_mode = payload[0];
            USHORT_T move_rate = payload[1] + (payload[2] << 8);
            USHORT_T temper_min = payload[3] + (payload[4] << 8);
            USHORT_T temper_max = payload[5] + (payload[6] << 8);

            tal_zg_read_attribute(1,
                                  CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                                  ATTR_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
                                  &cur_temper,
                                  sizeof(cur_temper));

            if (move_mode == 0x01)
            { // move up

                if (temper_max == 0 || temper_max >= COLOR_TEMP_MAX_MIREDS)
                {
                    tar_temper = COLOR_TEMP_MAX_MIREDS;
                }
                else if (temper_max >= cur_temper && temper_max <= COLOR_TEMP_MAX_MIREDS)
                {
                    tar_temper = temper_max;
                }
                else
                {
                    return OPRT_COM_ERROR;
                }
            }
            else if (move_mode == 0x03)
            { //move down

                if (temper_min == 0 || temper_min <= COLOR_TEMP_MIN_MIREDS)
                {
                    tar_temper = COLOR_TEMP_MIN_MIREDS;
                }
                else if (temper_min <= cur_temper && temper_min >= COLOR_TEMP_MIN_MIREDS)
                {
                    tar_temper = temper_min;
                }
                else
                {
                    return OPRT_COM_ERROR;
                }
            }
            else if (move_mode == 0x00)
            { // move stop

                app_light_ctrl_data_move_stop();
                return OPRT_OK;
            }
            else
            {
                return OPRT_COM_ERROR;
            }
            if (move_rate == 0)
            {
                move_rate = 1000;
            }

            USHORT_T trans_time_100ms = app_light_tools_get_abs_value(tar_temper - cur_temper) * 10 / move_rate;
            __app_color_z3_cmd_move_or_step_temperature_handler(cmd_type, tar_temper, trans_time_100ms);
        }
        break;
    }
    case CMD_STEP_COLOR_TEMPERATURE_COMMAND_ID:
    {
        if (payload_len == 6)
        {
            option_mask = payload[payload_len - 2];
            option_override = payload[payload_len - 1];
        }
        option = app_zcl_get_option_value(CLUSTER_LEVEL_CONTROL_CLUSTER_ID, option_mask, option_override);
        if (onoff == 1 || option == 0x01)
        {
            USHORT_T cur_temper = 0;
            USHORT_T tar_temper = 0;

            UCHAR_T step_mode = payload[0];
            USHORT_T step_size = payload[1] + (payload[2] << 8);
            USHORT_T transtime = payload[3] + (payload[4] << 8);
            USHORT_T step_temper_min = payload[5] + (payload[6] << 8);
            USHORT_T step_temper_max = payload[7] + (payload[8] << 8);

            tal_zg_read_attribute(1,
                                  CLUSTER_COLOR_CONTROL_CLUSTER_ID,
                                  ATTR_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
                                  &cur_temper,
                                  sizeof(cur_temper));

            if (step_mode == 0x01)
            { //Step up
                USHORT_T up_temper_max = COLOR_TEMP_MAX_MIREDS;
                if (step_temper_max == 0x0000 || step_temper_max > COLOR_TEMP_MAX_MIREDS)
                {
                    up_temper_max = COLOR_TEMP_MAX_MIREDS;
                }
                else
                {
                    up_temper_max = step_temper_max;
                }
                if (up_temper_max >= cur_temper)
                {
                    if (cur_temper + step_size > up_temper_max)
                    {
                        tar_temper = up_temper_max;
                    }
                    else
                    {
                        tar_temper = cur_temper + step_size;
                    }
                }
                else
                {
                    return OPRT_COM_ERROR;
                }
            }
            else if (step_mode == 0x03)
            { //Step down
                USHORT_T lower_temper_min = COLOR_TEMP_MIN_MIREDS;
                if (step_temper_min == 0 || step_temper_min < COLOR_TEMP_MIN_MIREDS)
                {
                    lower_temper_min = COLOR_TEMP_MIN_MIREDS;
                }
                else
                {
                    lower_temper_min = step_temper_min;
                }

                if (lower_temper_min <= cur_temper)
                {
                    if (cur_temper - step_size < lower_temper_min)
                    {
                        tar_temper = lower_temper_min;
                    }
                    else
                    {
                        tar_temper = cur_temper - step_size;
                    }
                }
                else
                {
                    return OPRT_COM_ERROR;
                }
            }
            else
            {
                return OPRT_COM_ERROR;
            }
            __app_color_z3_cmd_move_or_step_temperature_handler(cmd_type, tar_temper, transtime);
        }
        break;
    }
    case TY_CMD_SET_LIGHT_MODE_CMD_ID:
    {
        UCHAR_T mode = payload[0];
        __app_color_cmd_set_mode_handler(cmd_type, mode);
        break;
    }
    case TY_CMD_SET_TEMPERATURE_CMD_ID:
    {
        USHORT_T temper;
        temper = (USHORT_T)payload[0] + ((USHORT_T)payload[1] << 8);
        __app_color_ty_cmd_set_temperature_handler(cmd_type, temper);
        break;
    }
    case TY_CMD_SET_TY_SCENE_CMD_ID:
    {
        __app_color_cmd_set_ty_scene_handler(cmd_type, payload, payload_len);
        break;
    }
    case TY_CMD_SET_RHYTHM_MDOE_CMD_ID:
    {
        break;
    }
    case TY_CMD_SET_POWER_MEMORY_CMD_ID:
    {
        __app_color_cmd_set_power_memory_handler(cmd_type, payload, payload_len);
        break;
    }
    case TY_CMD_SET_DND_CMD_ID:
    {
        UCHAR_T no_disturb = payload[0];
        __app_color_cmd_set_do_not_disturb_handler(cmd_type, no_disturb);
        break;
    }
    case TY_CMD_SET_SWITCH_GRADIENT_CMD_ID:
    {
        __app_color_cmd_set_switch_gradient_handler(cmd_type, payload, payload_len);
        break;
    }
    
    default:
        break;
    }

    return OPRT_OK;
}
